<script>
import JTableRowHeader from './components/JTableRowHeader.vue';
import JTableColumnHeader from './components/JTableColumnHeader.vue';
import JTableHelper from './components/JTableHelper.js';
import JTableContainer from './components/JTableContainer.vue';
import Vue from 'vue';
export default {
  props: {
    table: {
      type: Object,
      default: () => null
    },
    workbook: {
      type: Object,
      default: () => null
    },
    headerHeight: {
      type: Number,
      default: 30
    },
    rowHeaderWidth: {
      type: Number,
      default: 40
    },
    scale: {
      type: Number,
      default: 1
    }
  },
  data() {
    return {
      fixVScrollWidth: 0,
      cols: [],
      rows: [],
      selection:[-1,-1,-1,-1],
      scrollX: 0,
      scrollY: 0,
    }
  },
  provide(){
    return {      
      CellClick: (cell)=>{this.$emit("CellClick",cell)},
      CellDoubleClick: (cell)=>{
        this.$emit("CellDoubleClick",cell)
      },
      ColumnChanged: (column)=>{this.$emit("ColumnChanged", column)},
      ColumnWidthChanged: (colIndex,newWidth,oldWidth)=>{
        console.log('columnwidthchanged:',colIndex,newWidth,oldWidth)
        this.$emit("ColumnWidthChanged", colIndex,newWidth,oldWidth)},
      RowHeigthChanged: (rowIndex,newHeight,oldHeight)=>{
        console.log('RowHeigthChanged:',rowIndex,newHeight,oldHeight)
        this.$emit("RowHeigthChanged", rowIndex,newHeight,oldHeight)},
      EditEnded: (cell,oldValue,newValue)=>{        
        this.$emit("EditEnded",cell, oldValue, newValue)
      },
      SelectionChanged: (selection)=>{
        this.selection = selection;        
        this.$emit("SelectionChanged",...arguments)
      },
      CellComponent:null
    }
  },
  watch: {
    table: {
      handler(newVal) {
        const config = { scale: this.scale }
        this.helper = Vue.observable(new JTableHelper(newVal, this.workbook, config));
        this.cols = this.helper.getColumns();
        this.rows = this.helper.getRows();
      },
      immediate: true
    },
    scale(val) {
      this.helper.scale = val;
    },
  },
  computed: {
    colWidthSum() {
      return this.cols.map(t => parseFloat(t.width)).reduce((a, b) => a + b, 0);
    }
  },
  created() {
    this.helper = new JTableHelper(this.table, this.workbook);
  },
  mounted() {
    this.$refs.scrolldiv.addEventListener('scroll', this.scrollDivScroll)
  },
  beforeUnmount() {
    this.$refs.scrolldiv.removeEventListener('scroll', this.scrollDivScroll)
  },
  render(h) {
    return h('div', {
      class: 'jtable-container',
      style: {
        transform: `scale(${this.helper.scale})`,
        transformOrigin: '0 0',
        height: `calc( 100% / ${this.helper.scale})`,
        width: `calc(100% / ${this.helper.scale})`
      },
      on: {
        wheel: (event) => {
          // 检查是否按下了 Ctrl 键
          if (!event.ctrlKey) return
          // 阻止浏览器默认缩放行为（如 Chrome 的页面缩放）
          event.preventDefault()
          // 根据滚轮方向调整缩放比例
          const delta = event.deltaY > 0 ? -0.1 : 0.1
          let newScale = this.helper.scale + delta
          // 限制缩放范围（例如 0.5 ~ 2.0）
          newScale = Math.min(Math.max(0.1, newScale), 2.0)
          this.helper.scale = Number(newScale.toFixed(3));
          this.$emit('update:scale', this.helper.scale)
        }
      }
    }, [
      h('div', {
        style: {
          height: `${this.headerHeight}px`,
          width: `${this.rowHeaderWidth}px`,
          position: 'absolute',
          zIndex: '2',
          background: '#dbdbdb',
          border: '1px solid rgb(154, 154, 154)',
          boxSizing: 'border-box',
          borderWidth: '1px 0.5px 0.5px 1px'
        }
      }),
      h(JTableColumnHeader, {
        style: {
          height: `${this.headerHeight}px`,
          transform: `translateX(-${this.scrollX}px)`,
          marginLeft: '40px',
          whiteSpace: 'nowrap',
        },
        props: {
          cols: this.cols,
          selection: this.selection,
          height: this.headerHeight,
          helper: this.helper,
          fixVScrollWidth: this.fixVScrollWidth,
        }
      }),
      h(JTableRowHeader, {
        style: {
          float: 'left',
          transform: `translateY(-${this.scrollY}px)`,
        },
        props: {
          rows: this.rows,
          helper: this.helper,
          selection: this.selection,
        }
      }),
      h('div', {
        ref: 'scrolldiv',
        style: {
          position: 'absolute',
          left: this.rowHeaderWidth + 'px',
          width: `calc( 100% - ${this.rowHeaderWidth}px )`,
          height: `calc( 100% - ${this.headerHeight}px )`,
          overflow: 'auto'
        }
      }, [
        h(JTableContainer, {
          props: {
            rows: this.rows,
            cols: this.cols,
            helper: this.helper,
          },
          style: {
            width: this.colWidthSum + 'px'
          }
        })
      ]
      )
    ])
  },
  methods: {
    getScrollbarWidth() {
      const div = document.createElement('div');
      div.style.width = '100px';
      div.style.height = '100px';
      div.style.overflow = 'scroll';
      div.style.position = 'absolute';
      div.style.top = '-9999px';
      document.body.appendChild(div);
      const scrollbarWidth = div.offsetWidth - div.clientWidth;
      document.body.removeChild(div);
      return scrollbarWidth;
    },
    scrollDivScroll() {
      this.scrollY = this.$refs.scrolldiv.scrollTop
      this.scrollX = this.$refs.scrolldiv.scrollLeft
    },
  }
}
</script>

<style>

</style>
<style scoped>
*{
  --theme-select-color: #109968
}
.jtable-container {
  font: 14px 宋体, Arial, sans-serif;
  width: 100%;
  height: fit-content;
  overflow: hidden;
}
</style>